diff --git a/.github/workflows/micropython.yml b/.github/workflows/micropython.yml index 2f2544b..8deac6b 100644 --- a/.github/workflows/micropython.yml +++ b/.github/workflows/micropython.yml @@ -7,9 +7,9 @@ on: types: [created] env: - MICROPYTHON_VERSION: v1.21.0 - PIMORONI_PICO_VERSION: v1.21.0 - WORKFLOW_VERSION: v2 + MICROPYTHON_VERSION: v1.23.0 + PIMORONI_PICO_VERSION: v1.23.0-1 + WORKFLOW_VERSION: v3 jobs: deps: @@ -64,15 +64,9 @@ jobs: - name: Badger 2040 shortname: badger2040 board: PIMORONI_BADGER2040 - # 0x10000000 + (2*1024*1024) - (1408*1024) - dir2uf2_fs_start: 269090816 - dir2uf2_fs_size: 1441792 - name: Badger 2040 W shortname: badger2040w board: PIMORONI_BADGER2040W - # 0x10000000 + (2*1024*1024) - (848*1024) - dir2uf2_fs_start: 269664256 - dir2uf2_fs_size: 868352 env: RELEASE_FILE: pimoroni-${{matrix.shortname}}-${{github.event.release.tag_name || github.sha}}-micropython.uf2 @@ -112,11 +106,18 @@ jobs: submodules: true path: pimoroni-pico + - name: "Py_Decl: Checkout py_decl" + uses: actions/checkout@v4 + with: + repository: gadgetoid/py_decl + ref: v0.0.1 + path: py_decl + # Check out dir2u2f - uses: actions/checkout@v4 with: repository: gadgetoid/dir2uf2 - ref: v0.0.1 + ref: v0.0.4 path: dir2uf2 # HACK: Patch startup overclock into Pico SDK @@ -129,7 +130,9 @@ jobs: - name: "HACK: CMakeLists.txt Disable C++ Exceptions Patch" shell: bash working-directory: micropython - run: git apply "${{env.FIRMWARE_DIR}}/micropython_nano_specs.patch" + run: | + git apply "${{env.FIRMWARE_DIR}}/932f76c6ba64c5a3e68de3324556d9979f09303b.patch" + git apply "${{env.FIRMWARE_DIR}}/micropython_nano_specs.patch" # Install apt packages - name: Install CCache & Compiler @@ -158,11 +161,16 @@ jobs: run: | cp firmware.uf2 ${{env.RELEASE_FILE}} + - name: "Py_Decl: Verify UF2" + shell: bash + run: | + python3 py_decl/py_decl.py --to-json --verify micropython/ports/rp2/build/${{ env.RELEASE_FILE }} + - name: Append Filesystem shell: bash run: | python3 -m pip install littlefs-python==0.4.0 - ./dir2uf2/dir2uf2 --fs-start ${{matrix.dir2uf2_fs_start}} --fs-size ${{matrix.dir2uf2_fs_size}} --append-to micropython/ports/rp2/build/${{env.RELEASE_FILE}} --manifest ${{env.BOARD_DIR}}/uf2-manifest.txt --filename with-badger-os.uf2 ${{env.BADGER_OS_DIR}}/ + ./dir2uf2/dir2uf2 --append-to micropython/ports/rp2/build/${{env.RELEASE_FILE}} --manifest ${{env.BOARD_DIR}}/uf2-manifest.txt --filename with-badger-os.uf2 ${{env.BADGER_OS_DIR}}/ - name: Store .uf2 as artifact uses: actions/upload-artifact@v4 diff --git a/badger_os/books/289-0-wind-in-the-willows-abridged.txt b/badger_os/books/289-0-wind-in-the-willows-abridged.txt index f6243fd..a488143 100644 --- a/badger_os/books/289-0-wind-in-the-willows-abridged.txt +++ b/badger_os/books/289-0-wind-in-the-willows-abridged.txt @@ -1,46 +1,8 @@ The Project Gutenberg eBook of The Wind in the Willows, by Kenneth Grahame -This eBook is for the use of anyone anywhere in the United States and -most other parts of the world at no cost and with almost no restrictions -whatsoever. You may copy it, give it away or re-use it under the terms -of the Project Gutenberg License included with this eBook or online at -www.gutenberg.org. If you are not located in the United States, you -will have to check the laws of the country where you are located before -using this eBook. - -Title: The Wind in the Willows - -Author: Kenneth Grahame - -Release Date: July, 1995 [eBook #289] -[Most recently updated: May 15, 2021] - -Language: English - -Character set encoding: UTF-8 - -Produced by: Mike Lough and David Widger - -*** START OF THE PROJECT GUTENBERG EBOOK THE WIND IN THE WILLOWS *** - -[Illustration] - - - - -The Wind in the Willows - -by Kenneth Grahame - -Author Of “The Golden Age,” “Dream Days,” Etc. - - Contents CHAPTER I. THE RIVER BANK - CHAPTER II. THE OPEN ROAD - - I. @@ -524,818 +486,15 @@ running water; and with his ear to the reed-stems he caught, at intervals, something of what the wind went whispering so constantly among them. +---- +NOTE: This book has been abridged to one chapter, you can find the +complete work at: https://www.gutenberg.org/ebooks/289 - -II. -THE OPEN ROAD - - -“Ratty,” said the Mole suddenly, one bright summer morning, “if you -please, I want to ask you a favour.” - -The Rat was sitting on the river bank, singing a little song. He had -just composed it himself, so he was very taken up with it, and would -not pay proper attention to Mole or anything else. Since early morning -he had been swimming in the river, in company with his friends the -ducks. And when the ducks stood on their heads suddenly, as ducks will, -he would dive down and tickle their necks, just under where their chins -would be if ducks had chins, till they were forced to come to the -surface again in a hurry, spluttering and angry and shaking their -feathers at him, for it is impossible to say quite _all_ you feel when -your head is under water. At last they implored him to go away and -attend to his own affairs and leave them to mind theirs. So the Rat -went away, and sat on the river bank in the sun, and made up a song -about them, which he called - -“DUCKS’ DITTY.” - -All along the backwater, -Through the rushes tall, -Ducks are a-dabbling, -Up tails all! -Ducks’ tails, drakes’ tails, -Yellow feet a-quiver, -Yellow bills all out of sight -Busy in the river! - -Slushy green undergrowth -Where the roach swim— -Here we keep our larder, -Cool and full and dim. - -Everyone for what he likes! -_We_ like to be -Heads down, tails up, -Dabbling free! - -High in the blue above -Swifts whirl and call— -_We_ are down a-dabbling -Uptails all! - - -“I don’t know that I think so _very_ much of that little song, Rat,” -observed the Mole cautiously. He was no poet himself and didn’t care -who knew it; and he had a candid nature. - -“Nor don’t the ducks neither,” replied the Rat cheerfully. “They say, -‘_Why_ can’t fellows be allowed to do what they like _when_ they like -and _as_ they like, instead of other fellows sitting on banks and -watching them all the time and making remarks and poetry and things -about them? What _nonsense_ it all is!’ That’s what the ducks say.” - -“So it is, so it is,” said the Mole, with great heartiness. - -“No, it isn’t!” cried the Rat indignantly. - -“Well then, it isn’t, it isn’t,” replied the Mole soothingly. “But what -I wanted to ask you was, won’t you take me to call on Mr. Toad? I’ve -heard so much about him, and I do so want to make his acquaintance.” - -“Why, certainly,” said the good-natured Rat, jumping to his feet and -dismissing poetry from his mind for the day. “Get the boat out, and -we’ll paddle up there at once. It’s never the wrong time to call on -Toad. Early or late he’s always the same fellow. Always good-tempered, -always glad to see you, always sorry when you go!” - -“He must be a very nice animal,” observed the Mole, as he got into the -boat and took the sculls, while the Rat settled himself comfortably in -the stern. - -“He is indeed the best of animals,” replied Rat. “So simple, so -good-natured, and so affectionate. Perhaps he’s not very clever—we -can’t all be geniuses; and it may be that he is both boastful and -conceited. But he has got some great qualities, has Toady.” - -Rounding a bend in the river, they came in sight of a handsome, -dignified old house of mellowed red brick, with well-kept lawns -reaching down to the water’s edge. - -“There’s Toad Hall,” said the Rat; “and that creek on the left, where -the notice-board says, ‘Private. No landing allowed,’ leads to his -boat-house, where we’ll leave the boat. The stables are over there to -the right. That’s the banqueting-hall you’re looking at now—very old, -that is. Toad is rather rich, you know, and this is really one of the -nicest houses in these parts, though we never admit as much to Toad.” - -They glided up the creek, and the Mole shipped his sculls as they -passed into the shadow of a large boat-house. Here they saw many -handsome boats, slung from the cross beams or hauled up on a slip, but -none in the water; and the place had an unused and a deserted air. - -The Rat looked around him. “I understand,” said he. “Boating is played -out. He’s tired of it, and done with it. I wonder what new fad he has -taken up now? Come along and let’s look him up. We shall hear all about -it quite soon enough.” - -They disembarked, and strolled across the gay flower-decked lawns in -search of Toad, whom they presently happened upon resting in a wicker -garden-chair, with a pre-occupied expression of face, and a large map -spread out on his knees. - -“Hooray!” he cried, jumping up on seeing them, “this is splendid!” He -shook the paws of both of them warmly, never waiting for an -introduction to the Mole. “How _kind_ of you!” he went on, dancing -round them. “I was just going to send a boat down the river for you, -Ratty, with strict orders that you were to be fetched up here at once, -whatever you were doing. I want you badly—both of you. Now what will -you take? Come inside and have something! You don’t know how lucky it -is, your turning up just now!” - -“Let’s sit quiet a bit, Toady!” said the Rat, throwing himself into an -easy chair, while the Mole took another by the side of him and made -some civil remark about Toad’s “delightful residence.” - -“Finest house on the whole river,” cried Toad boisterously. “Or -anywhere else, for that matter,” he could not help adding. - -Here the Rat nudged the Mole. Unfortunately the Toad saw him do it, and -turned very red. There was a moment’s painful silence. Then Toad burst -out laughing. “All right, Ratty,” he said. “It’s only my way, you know. -And it’s not such a very bad house, is it? You know you rather like it -yourself. Now, look here. Let’s be sensible. You are the very animals I -wanted. You’ve got to help me. It’s most important!” - -“It’s about your rowing, I suppose,” said the Rat, with an innocent -air. “You’re getting on fairly well, though you splash a good bit -still. With a great deal of patience, and any quantity of coaching, you -may——” - -“O, pooh! boating!” interrupted the Toad, in great disgust. “Silly -boyish amusement. I’ve given that up _long_ ago. Sheer waste of time, -that’s what it is. It makes me downright sorry to see you fellows, who -ought to know better, spending all your energies in that aimless -manner. No, I’ve discovered the real thing, the only genuine occupation -for a life time. I propose to devote the remainder of mine to it, and -can only regret the wasted years that lie behind me, squandered in -trivialities. Come with me, dear Ratty, and your amiable friend also, -if he will be so very good, just as far as the stable-yard, and you -shall see what you shall see!” - -He led the way to the stable-yard accordingly, the Rat following with a -most mistrustful expression; and there, drawn out of the coach house -into the open, they saw a gipsy caravan, shining with newness, painted -a canary-yellow picked out with green, and red wheels. - -“There you are!” cried the Toad, straddling and expanding himself. -“There’s real life for you, embodied in that little cart. The open -road, the dusty highway, the heath, the common, the hedgerows, the -rolling downs! Camps, villages, towns, cities! Here to-day, up and off -to somewhere else to-morrow! Travel, change, interest, excitement! The -whole world before you, and a horizon that’s always changing! And mind! -this is the very finest cart of its sort that was ever built, without -any exception. Come inside and look at the arrangements. Planned ’em -all myself, I did!” - -The Mole was tremendously interested and excited, and followed him -eagerly up the steps and into the interior of the caravan. The Rat only -snorted and thrust his hands deep into his pockets, remaining where he -was. - -It was indeed very compact and comfortable. Little sleeping bunks—a -little table that folded up against the wall—a cooking-stove, lockers, -bookshelves, a bird-cage with a bird in it; and pots, pans, jugs and -kettles of every size and variety. - -“All complete!” said the Toad triumphantly, pulling open a locker. “You -see—biscuits, potted lobster, sardines—everything you can possibly -want. Soda-water here—baccy there—letter-paper, bacon, jam, cards and -dominoes—you’ll find,” he continued, as they descended the steps again, -“you’ll find that nothing what ever has been forgotten, when we make -our start this afternoon.” - -“I beg your pardon,” said the Rat slowly, as he chewed a straw, “but -did I overhear you say something about ‘_we_,’ and ‘_start_,’ and -‘_this afternoon?_’” - -“Now, you dear good old Ratty,” said Toad, imploringly, “don’t begin -talking in that stiff and sniffy sort of way, because you know you’ve -_got_ to come. I can’t possibly manage without you, so please consider -it settled, and don’t argue—it’s the one thing I can’t stand. You -surely don’t mean to stick to your dull fusty old river all your life, -and just live in a hole in a bank, and _boat?_ I want to show you the -world! I’m going to make an _animal_ of you, my boy!” - -“I don’t care,” said the Rat, doggedly. “I’m not coming, and that’s -flat. And I _am_ going to stick to my old river, _and_ live in a hole, -_and_ boat, as I’ve always done. And what’s more, Mole’s going to stick -to me and do as I do, aren’t you, Mole?” - -“Of course I am,” said the Mole, loyally. “I’ll always stick to you, -Rat, and what you say is to be—has got to be. All the same, it sounds -as if it might have been—well, rather fun, you know!” he added, -wistfully. Poor Mole! The Life Adventurous was so new a thing to him, -and so thrilling; and this fresh aspect of it was so tempting; and he -had fallen in love at first sight with the canary-coloured cart and all -its little fitments. - -The Rat saw what was passing in his mind, and wavered. He hated -disappointing people, and he was fond of the Mole, and would do almost -anything to oblige him. Toad was watching both of them closely. - -“Come along in, and have some lunch,” he said, diplomatically, “and -we’ll talk it over. We needn’t decide anything in a hurry. Of course, -_I_ don’t really care. I only want to give pleasure to you fellows. -‘Live for others!’ That’s my motto in life.” - -During luncheon—which was excellent, of course, as everything at Toad -Hall always was—the Toad simply let himself go. Disregarding the Rat, -he proceeded to play upon the inexperienced Mole as on a harp. -Naturally a voluble animal, and always mastered by his imagination, he -painted the prospects of the trip and the joys of the open life and the -roadside in such glowing colours that the Mole could hardly sit in his -chair for excitement. Somehow, it soon seemed taken for granted by all -three of them that the trip was a settled thing; and the Rat, though -still unconvinced in his mind, allowed his good-nature to over-ride his -personal objections. He could not bear to disappoint his two friends, -who were already deep in schemes and anticipations, planning out each -day’s separate occupation for several weeks ahead. - -When they were quite ready, the now triumphant Toad led his companions -to the paddock and set them to capture the old grey horse, who, without -having been consulted, and to his own extreme annoyance, had been told -off by Toad for the dustiest job in this dusty expedition. He frankly -preferred the paddock, and took a deal of catching. Meantime Toad -packed the lockers still tighter with necessaries, and hung nosebags, -nets of onions, bundles of hay, and baskets from the bottom of the -cart. At last the horse was caught and harnessed, and they set off, all -talking at once, each animal either trudging by the side of the cart or -sitting on the shaft, as the humour took him. It was a golden -afternoon. The smell of the dust they kicked up was rich and -satisfying; out of thick orchards on either side the road, birds called -and whistled to them cheerily; good-natured wayfarers, passing them, -gave them “Good-day,” or stopped to say nice things about their -beautiful cart; and rabbits, sitting at their front doors in the -hedgerows, held up their fore-paws, and said, “O my! O my! O my!” - -Late in the evening, tired and happy and miles from home, they drew up -on a remote common far from habitations, turned the horse loose to -graze, and ate their simple supper sitting on the grass by the side of -the cart. Toad talked big about all he was going to do in the days to -come, while stars grew fuller and larger all around them, and a yellow -moon, appearing suddenly and silently from nowhere in particular, came -to keep them company and listen to their talk. At last they turned in -to their little bunks in the cart; and Toad, kicking out his legs, -sleepily said, “Well, good night, you fellows! This is the real life -for a gentleman! Talk about your old river!” - -“I _don’t_ talk about my river,” replied the patient Rat. “You _know_ I -don’t, Toad. But I _think_ about it,” he added pathetically, in a lower -tone: “I think about it—all the time!” - -The Mole reached out from under his blanket, felt for the Rat’s paw in -the darkness, and gave it a squeeze. “I’ll do whatever you like, -Ratty,” he whispered. “Shall we run away to-morrow morning, quite -early—_very_ early—and go back to our dear old hole on the river?” - -“No, no, we’ll see it out,” whispered back the Rat. “Thanks awfully, -but I ought to stick by Toad till this trip is ended. It wouldn’t be -safe for him to be left to himself. It won’t take very long. His fads -never do. Good night!” - -The end was indeed nearer than even the Rat suspected. - -After so much open air and excitement the Toad slept very soundly, and -no amount of shaking could rouse him out of bed next morning. So the -Mole and Rat turned to, quietly and manfully, and while the Rat saw to -the horse, and lit a fire, and cleaned last night’s cups and platters, -and got things ready for breakfast, the Mole trudged off to the nearest -village, a long way off, for milk and eggs and various necessaries the -Toad had, of course, forgotten to provide. The hard work had all been -done, and the two animals were resting, thoroughly exhausted, by the -time Toad appeared on the scene, fresh and gay, remarking what a -pleasant easy life it was they were all leading now, after the cares -and worries and fatigues of housekeeping at home. - -They had a pleasant ramble that day over grassy downs and along narrow -by-lanes, and camped as before, on a common, only this time the two -guests took care that Toad should do his fair share of work. In -consequence, when the time came for starting next morning, Toad was by -no means so rapturous about the simplicity of the primitive life, and -indeed attempted to resume his place in his bunk, whence he was hauled -by force. Their way lay, as before, across country by narrow lanes, and -it was not till the afternoon that they came out on the high-road, -their first high-road; and there disaster, fleet and unforeseen, sprang -out on them—disaster momentous indeed to their expedition, but simply -overwhelming in its effect on the after-career of Toad. - -They were strolling along the high-road easily, the Mole by the horse’s -head, talking to him, since the horse had complained that he was being -frightfully left out of it, and nobody considered him in the least; the -Toad and the Water Rat walking behind the cart talking together—at -least Toad was talking, and Rat was saying at intervals, “Yes, -precisely; and what did _you_ say to _him?_”—and thinking all the time -of something very different, when far behind them they heard a faint -warning hum; like the drone of a distant bee. Glancing back, they saw a -small cloud of dust, with a dark centre of energy, advancing on them at -incredible speed, while from out the dust a faint “Poop-poop!” wailed -like an uneasy animal in pain. Hardly regarding it, they turned to -resume their conversation, when in an instant (as it seemed) the -peaceful scene was changed, and with a blast of wind and a whirl of -sound that made them jump for the nearest ditch, It was on them! The -“Poop-poop” rang with a brazen shout in their ears, they had a moment’s -glimpse of an interior of glittering plate-glass and rich morocco, and -the magnificent motor-car, immense, breath-snatching, passionate, with -its pilot tense and hugging his wheel, possessed all earth and air for -the fraction of a second, flung an enveloping cloud of dust that -blinded and enwrapped them utterly, and then dwindled to a speck in the -far distance, changed back into a droning bee once more. - -The old grey horse, dreaming, as he plodded along, of his quiet -paddock, in a new raw situation such as this simply abandoned himself -to his natural emotions. Rearing, plunging, backing steadily, in spite -of all the Mole’s efforts at his head, and all the Mole’s lively -language directed at his better feelings, he drove the cart backwards -towards the deep ditch at the side of the road. It wavered an -instant—then there was a heartrending crash—and the canary-coloured -cart, their pride and their joy, lay on its side in the ditch, an -irredeemable wreck. - -The Rat danced up and down in the road, simply transported with -passion. “You villains!” he shouted, shaking both fists, “You -scoundrels, you highwaymen, you—you—roadhogs!—I’ll have the law of you! -I’ll report you! I’ll take you through all the Courts!” His -home-sickness had quite slipped away from him, and for the moment he -was the skipper of the canary-coloured vessel driven on a shoal by the -reckless jockeying of rival mariners, and he was trying to recollect -all the fine and biting things he used to say to masters of -steam-launches when their wash, as they drove too near the bank, used -to flood his parlour-carpet at home. - -Toad sat straight down in the middle of the dusty road, his legs -stretched out before him, and stared fixedly in the direction of the -disappearing motor-car. He breathed short, his face wore a placid -satisfied expression, and at intervals he faintly murmured “Poop-poop!” - -The Mole was busy trying to quiet the horse, which he succeeded in -doing after a time. Then he went to look at the cart, on its side in -the ditch. It was indeed a sorry sight. Panels and windows smashed, -axles hopelessly bent, one wheel off, sardine-tins scattered over the -wide world, and the bird in the bird-cage sobbing pitifully and calling -to be let out. - -The Rat came to help him, but their united efforts were not sufficient -to right the cart. “Hi! Toad!” they cried. “Come and bear a hand, can’t -you!” - -The Toad never answered a word, or budged from his seat in the road; so -they went to see what was the matter with him. They found him in a sort -of a trance, a happy smile on his face, his eyes still fixed on the -dusty wake of their destroyer. At intervals he was still heard to -murmur “Poop-poop!” - -The Rat shook him by the shoulder. “Are you coming to help us, Toad?” -he demanded sternly. - -“Glorious, stirring sight!” murmured Toad, never offering to move. “The -poetry of motion! The _real_ way to travel! The _only_ way to travel! -Here to-day—in next week to-morrow! Villages skipped, towns and cities -jumped—always somebody else’s horizon! O bliss! O poop-poop! O my! O -my!” - -“O _stop_ being an ass, Toad!” cried the Mole despairingly. - -“And to think I never _knew!_” went on the Toad in a dreamy monotone. -“All those wasted years that lie behind me, I never knew, never even -_dreamt!_ But _now_—but now that I know, now that I fully realise! O -what a flowery track lies spread before me, henceforth! What -dust-clouds shall spring up behind me as I speed on my reckless way! -What carts I shall fling carelessly into the ditch in the wake of my -magnificent onset! Horrid little carts—common carts—canary-coloured -carts!” - -“What are we to do with him?” asked the Mole of the Water Rat. - -“Nothing at all,” replied the Rat firmly. “Because there is really -nothing to be done. You see, I know him from of old. He is now -possessed. He has got a new craze, and it always takes him that way, in -its first stage. He’ll continue like that for days now, like an animal -walking in a happy dream, quite useless for all practical purposes. -Never mind him. Let’s go and see what there is to be done about the -cart.” - -A careful inspection showed them that, even if they succeeded in -righting it by themselves, the cart would travel no longer. The axles -were in a hopeless state, and the missing wheel was shattered into -pieces. - -The Rat knotted the horse’s reins over his back and took him by the -head, carrying the bird cage and its hysterical occupant in the other -hand. “Come on!” he said grimly to the Mole. “It’s five or six miles to -the nearest town, and we shall just have to walk it. The sooner we make -a start the better.” - -“But what about Toad?” asked the Mole anxiously, as they set off -together. “We can’t leave him here, sitting in the middle of the road -by himself, in the distracted state he’s in! It’s not safe. Supposing -another Thing were to come along?” - -“O, _bother_ Toad,” said the Rat savagely; “I’ve done with him!” - -They had not proceeded very far on their way, however, when there was a -pattering of feet behind them, and Toad caught them up and thrust a paw -inside the elbow of each of them; still breathing short and staring -into vacancy. - -“Now, look here, Toad!” said the Rat sharply: “as soon as we get to the -town, you’ll have to go straight to the police-station, and see if they -know anything about that motor-car and who it belongs to, and lodge a -complaint against it. And then you’ll have to go to a blacksmith’s or a -wheelwright’s and arrange for the cart to be fetched and mended and put -to rights. It’ll take time, but it’s not quite a hopeless smash. -Meanwhile, the Mole and I will go to an inn and find comfortable rooms -where we can stay till the cart’s ready, and till your nerves have -recovered their shock.” - -“Police-station! Complaint!” murmured Toad dreamily. “Me _complain_ of -that beautiful, that heavenly vision that has been vouchsafed me! -_Mend_ the _cart!_ I’ve done with carts for ever. I never want to see -the cart, or to hear of it, again. O, Ratty! You can’t think how -obliged I am to you for consenting to come on this trip! I wouldn’t -have gone without you, and then I might never have seen that—that swan, -that sunbeam, that thunderbolt! I might never have heard that -entrancing sound, or smelt that bewitching smell! I owe it all to you, -my best of friends!” - -The Rat turned from him in despair. “You see what it is?” he said to -the Mole, addressing him across Toad’s head: “He’s quite hopeless. I -give it up—when we get to the town we’ll go to the railway station, and -with luck we may pick up a train there that’ll get us back to riverbank -to-night. And if ever you catch me going a-pleasuring with this -provoking animal again!”—He snorted, and during the rest of that weary -trudge addressed his remarks exclusively to Mole. - -On reaching the town they went straight to the station and deposited -Toad in the second-class waiting-room, giving a porter twopence to keep -a strict eye on him. They then left the horse at an inn stable, and -gave what directions they could about the cart and its contents. -Eventually, a slow train having landed them at a station not very far -from Toad Hall, they escorted the spell-bound, sleep-walking Toad to -his door, put him inside it, and instructed his housekeeper to feed -him, undress him, and put him to bed. Then they got out their boat from -the boat-house, sculled down the river home, and at a very late hour -sat down to supper in their own cosy riverside parlour, to the Rat’s -great joy and contentment. - -The following evening the Mole, who had risen late and taken things -very easy all day, was sitting on the bank fishing, when the Rat, who -had been looking up his friends and gossiping, came strolling along to -find him. “Heard the news?” he said. “There’s nothing else being talked -about, all along the river bank. Toad went up to Town by an early train -this morning. And he has ordered a large and very expensive motor-car.” - - - -*** END OF THE PROJECT GUTENBERG EBOOK THE WIND IN THE WILLOWS *** - -***** This file should be named 289-0.txt or 289-0.zip ***** -This and all associated files of various formats will be found in: - https://www.gutenberg.org/2/8/289/ - -Updated editions will replace the previous one--the old editions will -be renamed. - -Creating the works from print editions not protected by U.S. copyright -law means that no one owns a United States copyright in these works, -so the Foundation (and you!) can copy and distribute it in the -United States without permission and without paying copyright -royalties. Special rules, set forth in the General Terms of Use part -of this license, apply to copying and distributing Project -Gutenberg-tm electronic works to protect the PROJECT GUTENBERG-tm -concept and trademark. Project Gutenberg is a registered trademark, -and may not be used if you charge for an eBook, except by following -the terms of the trademark license, including paying royalties for use -of the Project Gutenberg trademark. If you do not charge anything for -copies of this eBook, complying with the trademark license is very -easy. You may use this eBook for nearly any purpose such as creation -of derivative works, reports, performances and research. Project -Gutenberg eBooks may be modified and printed and given away--you may -do practically ANYTHING in the United States with eBooks not protected -by U.S. copyright law. Redistribution is subject to the trademark -license, especially commercial redistribution. - -START: FULL LICENSE - -THE FULL PROJECT GUTENBERG LICENSE -PLEASE READ THIS BEFORE YOU DISTRIBUTE OR USE THIS WORK - -To protect the Project Gutenberg-tm mission of promoting the free -distribution of electronic works, by using or distributing this work -(or any other work associated in any way with the phrase "Project -Gutenberg"), you agree to comply with all the terms of the Full -Project Gutenberg-tm License available with this file or online at -www.gutenberg.org/license. - -Section 1. General Terms of Use and Redistributing Project -Gutenberg-tm electronic works - -1.A. By reading or using any part of this Project Gutenberg-tm -electronic work, you indicate that you have read, understand, agree to -and accept all the terms of this license and intellectual property -(trademark/copyright) agreement. If you do not agree to abide by all -the terms of this agreement, you must cease using and return or -destroy all copies of Project Gutenberg-tm electronic works in your -possession. If you paid a fee for obtaining a copy of or access to a -Project Gutenberg-tm electronic work and you do not agree to be bound -by the terms of this agreement, you may obtain a refund from the -person or entity to whom you paid the fee as set forth in paragraph -1.E.8. - -1.B. "Project Gutenberg" is a registered trademark. It may only be -used on or associated in any way with an electronic work by people who -agree to be bound by the terms of this agreement. There are a few -things that you can do with most Project Gutenberg-tm electronic works -even without complying with the full terms of this agreement. See -paragraph 1.C below. There are a lot of things you can do with Project -Gutenberg-tm electronic works if you follow the terms of this -agreement and help preserve free future access to Project Gutenberg-tm -electronic works. See paragraph 1.E below. - -1.C. The Project Gutenberg Literary Archive Foundation ("the -Foundation" or PGLAF), owns a compilation copyright in the collection -of Project Gutenberg-tm electronic works. Nearly all the individual -works in the collection are in the public domain in the United -States. If an individual work is unprotected by copyright law in the -United States and you are located in the United States, we do not -claim a right to prevent you from copying, distributing, performing, -displaying or creating derivative works based on the work as long as -all references to Project Gutenberg are removed. Of course, we hope -that you will support the Project Gutenberg-tm mission of promoting -free access to electronic works by freely sharing Project Gutenberg-tm -works in compliance with the terms of this agreement for keeping the -Project Gutenberg-tm name associated with the work. You can easily -comply with the terms of this agreement by keeping this work in the -same format with its attached full Project Gutenberg-tm License when -you share it without charge with others. - -1.D. The copyright laws of the place where you are located also govern -what you can do with this work. Copyright laws in most countries are -in a constant state of change. If you are outside the United States, -check the laws of your country in addition to the terms of this -agreement before downloading, copying, displaying, performing, -distributing or creating derivative works based on this work or any -other Project Gutenberg-tm work. The Foundation makes no -representations concerning the copyright status of any work in any -country other than the United States. - -1.E. Unless you have removed all references to Project Gutenberg: - -1.E.1. The following sentence, with active links to, or other -immediate access to, the full Project Gutenberg-tm License must appear -prominently whenever any copy of a Project Gutenberg-tm work (any work -on which the phrase "Project Gutenberg" appears, or with which the -phrase "Project Gutenberg" is associated) is accessed, displayed, -performed, viewed, copied or distributed: - - This eBook is for the use of anyone anywhere in the United States and - most other parts of the world at no cost and with almost no - restrictions whatsoever. You may copy it, give it away or re-use it - under the terms of the Project Gutenberg License included with this - eBook or online at www.gutenberg.org. If you are not located in the - United States, you will have to check the laws of the country where - you are located before using this eBook. - -1.E.2. If an individual Project Gutenberg-tm electronic work is -derived from texts not protected by U.S. copyright law (does not -contain a notice indicating that it is posted with permission of the -copyright holder), the work can be copied and distributed to anyone in -the United States without paying any fees or charges. If you are -redistributing or providing access to a work with the phrase "Project -Gutenberg" associated with or appearing on the work, you must comply -either with the requirements of paragraphs 1.E.1 through 1.E.7 or -obtain permission for the use of the work and the Project Gutenberg-tm -trademark as set forth in paragraphs 1.E.8 or 1.E.9. - -1.E.3. If an individual Project Gutenberg-tm electronic work is posted -with the permission of the copyright holder, your use and distribution -must comply with both paragraphs 1.E.1 through 1.E.7 and any -additional terms imposed by the copyright holder. Additional terms -will be linked to the Project Gutenberg-tm License for all works -posted with the permission of the copyright holder found at the -beginning of this work. - -1.E.4. Do not unlink or detach or remove the full Project Gutenberg-tm -License terms from this work, or any files containing a part of this -work or any other work associated with Project Gutenberg-tm. - -1.E.5. Do not copy, display, perform, distribute or redistribute this -electronic work, or any part of this electronic work, without -prominently displaying the sentence set forth in paragraph 1.E.1 with -active links or immediate access to the full terms of the Project -Gutenberg-tm License. - -1.E.6. You may convert to and distribute this work in any binary, -compressed, marked up, nonproprietary or proprietary form, including -any word processing or hypertext form. However, if you provide access -to or distribute copies of a Project Gutenberg-tm work in a format -other than "Plain Vanilla ASCII" or other format used in the official -version posted on the official Project Gutenberg-tm website -(www.gutenberg.org), you must, at no additional cost, fee or expense -to the user, provide a copy, a means of exporting a copy, or a means -of obtaining a copy upon request, of the work in its original "Plain -Vanilla ASCII" or other form. Any alternate format must include the -full Project Gutenberg-tm License as specified in paragraph 1.E.1. - -1.E.7. Do not charge a fee for access to, viewing, displaying, -performing, copying or distributing any Project Gutenberg-tm works -unless you comply with paragraph 1.E.8 or 1.E.9. - -1.E.8. You may charge a reasonable fee for copies of or providing -access to or distributing Project Gutenberg-tm electronic works -provided that: - -* You pay a royalty fee of 20% of the gross profits you derive from - the use of Project Gutenberg-tm works calculated using the method - you already use to calculate your applicable taxes. The fee is owed - to the owner of the Project Gutenberg-tm trademark, but he has - agreed to donate royalties under this paragraph to the Project - Gutenberg Literary Archive Foundation. Royalty payments must be paid - within 60 days following each date on which you prepare (or are - legally required to prepare) your periodic tax returns. Royalty - payments should be clearly marked as such and sent to the Project - Gutenberg Literary Archive Foundation at the address specified in - Section 4, "Information about donations to the Project Gutenberg - Literary Archive Foundation." - -* You provide a full refund of any money paid by a user who notifies - you in writing (or by e-mail) within 30 days of receipt that s/he - does not agree to the terms of the full Project Gutenberg-tm - License. You must require such a user to return or destroy all - copies of the works possessed in a physical medium and discontinue - all use of and all access to other copies of Project Gutenberg-tm - works. - -* You provide, in accordance with paragraph 1.F.3, a full refund of - any money paid for a work or a replacement copy, if a defect in the - electronic work is discovered and reported to you within 90 days of - receipt of the work. - -* You comply with all other terms of this agreement for free - distribution of Project Gutenberg-tm works. - -1.E.9. If you wish to charge a fee or distribute a Project -Gutenberg-tm electronic work or group of works on different terms than -are set forth in this agreement, you must obtain permission in writing -from the Project Gutenberg Literary Archive Foundation, the manager of -the Project Gutenberg-tm trademark. Contact the Foundation as set -forth in Section 3 below. - -1.F. - -1.F.1. Project Gutenberg volunteers and employees expend considerable -effort to identify, do copyright research on, transcribe and proofread -works not protected by U.S. copyright law in creating the Project -Gutenberg-tm collection. Despite these efforts, Project Gutenberg-tm -electronic works, and the medium on which they may be stored, may -contain "Defects," such as, but not limited to, incomplete, inaccurate -or corrupt data, transcription errors, a copyright or other -intellectual property infringement, a defective or damaged disk or -other medium, a computer virus, or computer codes that damage or -cannot be read by your equipment. - -1.F.2. LIMITED WARRANTY, DISCLAIMER OF DAMAGES - Except for the "Right -of Replacement or Refund" described in paragraph 1.F.3, the Project -Gutenberg Literary Archive Foundation, the owner of the Project -Gutenberg-tm trademark, and any other party distributing a Project -Gutenberg-tm electronic work under this agreement, disclaim all -liability to you for damages, costs and expenses, including legal -fees. YOU AGREE THAT YOU HAVE NO REMEDIES FOR NEGLIGENCE, STRICT -LIABILITY, BREACH OF WARRANTY OR BREACH OF CONTRACT EXCEPT THOSE -PROVIDED IN PARAGRAPH 1.F.3. YOU AGREE THAT THE FOUNDATION, THE -TRADEMARK OWNER, AND ANY DISTRIBUTOR UNDER THIS AGREEMENT WILL NOT BE -LIABLE TO YOU FOR ACTUAL, DIRECT, INDIRECT, CONSEQUENTIAL, PUNITIVE OR -INCIDENTAL DAMAGES EVEN IF YOU GIVE NOTICE OF THE POSSIBILITY OF SUCH -DAMAGE. - -1.F.3. LIMITED RIGHT OF REPLACEMENT OR REFUND - If you discover a -defect in this electronic work within 90 days of receiving it, you can -receive a refund of the money (if any) you paid for it by sending a -written explanation to the person you received the work from. If you -received the work on a physical medium, you must return the medium -with your written explanation. The person or entity that provided you -with the defective work may elect to provide a replacement copy in -lieu of a refund. If you received the work electronically, the person -or entity providing it to you may choose to give you a second -opportunity to receive the work electronically in lieu of a refund. If -the second copy is also defective, you may demand a refund in writing -without further opportunities to fix the problem. - -1.F.4. Except for the limited right of replacement or refund set forth -in paragraph 1.F.3, this work is provided to you 'AS-IS', WITH NO -OTHER WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT -LIMITED TO WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PURPOSE. - -1.F.5. Some states do not allow disclaimers of certain implied -warranties or the exclusion or limitation of certain types of -damages. If any disclaimer or limitation set forth in this agreement -violates the law of the state applicable to this agreement, the -agreement shall be interpreted to make the maximum disclaimer or -limitation permitted by the applicable state law. The invalidity or -unenforceability of any provision of this agreement shall not void the -remaining provisions. - -1.F.6. INDEMNITY - You agree to indemnify and hold the Foundation, the -trademark owner, any agent or employee of the Foundation, anyone -providing copies of Project Gutenberg-tm electronic works in -accordance with this agreement, and any volunteers associated with the -production, promotion and distribution of Project Gutenberg-tm -electronic works, harmless from all liability, costs and expenses, -including legal fees, that arise directly or indirectly from any of -the following which you do or cause to occur: (a) distribution of this -or any Project Gutenberg-tm work, (b) alteration, modification, or -additions or deletions to any Project Gutenberg-tm work, and (c) any -Defect you cause. - -Section 2. Information about the Mission of Project Gutenberg-tm - -Project Gutenberg-tm is synonymous with the free distribution of -electronic works in formats readable by the widest variety of -computers including obsolete, old, middle-aged and new computers. It -exists because of the efforts of hundreds of volunteers and donations -from people in all walks of life. - -Volunteers and financial support to provide volunteers with the -assistance they need are critical to reaching Project Gutenberg-tm's -goals and ensuring that the Project Gutenberg-tm collection will -remain freely available for generations to come. In 2001, the Project -Gutenberg Literary Archive Foundation was created to provide a secure -and permanent future for Project Gutenberg-tm and future -generations. To learn more about the Project Gutenberg Literary -Archive Foundation and how your efforts and donations can help, see -Sections 3 and 4 and the Foundation information page at -www.gutenberg.org - -Section 3. Information about the Project Gutenberg Literary -Archive Foundation - -The Project Gutenberg Literary Archive Foundation is a non-profit -501(c)(3) educational corporation organized under the laws of the -state of Mississippi and granted tax exempt status by the Internal -Revenue Service. The Foundation's EIN or federal tax identification -number is 64-6221541. Contributions to the Project Gutenberg Literary -Archive Foundation are tax deductible to the full extent permitted by -U.S. federal laws and your state's laws. - -The Foundation's business office is located at 809 North 1500 West, -Salt Lake City, UT 84116, (801) 596-1887. Email contact links and up -to date contact information can be found at the Foundation's website -and official page at www.gutenberg.org/contact - -Section 4. Information about Donations to the Project Gutenberg -Literary Archive Foundation - -Project Gutenberg-tm depends upon and cannot survive without -widespread public support and donations to carry out its mission of -increasing the number of public domain and licensed works that can be -freely distributed in machine-readable form accessible by the widest -array of equipment including outdated equipment. Many small donations -($1 to $5,000) are particularly important to maintaining tax exempt -status with the IRS. - -The Foundation is committed to complying with the laws regulating -charities and charitable donations in all 50 states of the United -States. Compliance requirements are not uniform and it takes a -considerable effort, much paperwork and many fees to meet and keep up -with these requirements. We do not solicit donations in locations -where we have not received written confirmation of compliance. To SEND -DONATIONS or determine the status of compliance for any particular -state visit www.gutenberg.org/donate - -While we cannot and do not solicit contributions from states where we -have not met the solicitation requirements, we know of no prohibition -against accepting unsolicited donations from donors in such states who -approach us with offers to donate. - -International donations are gratefully accepted, but we cannot make -any statements concerning tax treatment of donations received from -outside the United States. U.S. laws alone swamp our small staff. - -Please check the Project Gutenberg web pages for current donation -methods and addresses. Donations are accepted in a number of other -ways including checks, online payments and credit card donations. To -donate, please visit: www.gutenberg.org/donate - -Section 5. General Information About Project Gutenberg-tm electronic works - -Professor Michael S. Hart was the originator of the Project -Gutenberg-tm concept of a library of electronic works that could be -freely shared with anyone. For forty years, he produced and -distributed Project Gutenberg-tm eBooks with only a loose network of -volunteer support. - -Project Gutenberg-tm eBooks are often created from several printed -editions, all of which are confirmed as not protected by copyright in -the U.S. unless a copyright notice is included. Thus, we do not -necessarily keep eBooks in compliance with any particular paper -edition. - -Most people start at our website which has the main PG search -facility: www.gutenberg.org - -This website includes information about Project Gutenberg-tm, -including how to make donations to the Project Gutenberg Literary -Archive Foundation, how to help produce our new eBooks, and how to -subscribe to our email newsletter to hear about new eBooks. - - +This eBook is for the use of anyone anywhere in the United States and +most other parts of the world at no cost and with almost no +restrictions whatsoever. You may copy it, give it away or re-use it +under the terms of the Project Gutenberg License included with this +eBook or online at www.gutenberg.org. If you are not located in the +United States, you will have to check the laws of the country where +you are located before using this eBook. \ No newline at end of file diff --git a/badger_os/examples/icon-badge.jpg b/badger_os/examples/icon-badge.jpg deleted file mode 100644 index 0b86070..0000000 Binary files a/badger_os/examples/icon-badge.jpg and /dev/null differ diff --git a/badger_os/examples/icon-badge.png b/badger_os/examples/icon-badge.png new file mode 100644 index 0000000..8540985 Binary files /dev/null and b/badger_os/examples/icon-badge.png differ diff --git a/badger_os/examples/icon-clock.jpg b/badger_os/examples/icon-clock.jpg deleted file mode 100644 index 48c37df..0000000 Binary files a/badger_os/examples/icon-clock.jpg and /dev/null differ diff --git a/badger_os/examples/icon-clock.png b/badger_os/examples/icon-clock.png new file mode 100644 index 0000000..a71fa2f Binary files /dev/null and b/badger_os/examples/icon-clock.png differ diff --git a/badger_os/examples/icon-ebook.jpg b/badger_os/examples/icon-ebook.jpg deleted file mode 100644 index 4e7551f..0000000 Binary files a/badger_os/examples/icon-ebook.jpg and /dev/null differ diff --git a/badger_os/examples/icon-ebook.png b/badger_os/examples/icon-ebook.png new file mode 100644 index 0000000..3eb7c20 Binary files /dev/null and b/badger_os/examples/icon-ebook.png differ diff --git a/badger_os/examples/icon-fonts.jpg b/badger_os/examples/icon-fonts.jpg deleted file mode 100644 index cef072f..0000000 Binary files a/badger_os/examples/icon-fonts.jpg and /dev/null differ diff --git a/badger_os/examples/icon-fonts.png b/badger_os/examples/icon-fonts.png new file mode 100644 index 0000000..40cd1cc Binary files /dev/null and b/badger_os/examples/icon-fonts.png differ diff --git a/badger_os/examples/icon-help.jpg b/badger_os/examples/icon-help.jpg deleted file mode 100644 index 80c3f6f..0000000 Binary files a/badger_os/examples/icon-help.jpg and /dev/null differ diff --git a/badger_os/examples/icon-help.png b/badger_os/examples/icon-help.png new file mode 100644 index 0000000..bfdf88b Binary files /dev/null and b/badger_os/examples/icon-help.png differ diff --git a/badger_os/examples/icon-image.jpg b/badger_os/examples/icon-image.jpg deleted file mode 100644 index e8ab644..0000000 Binary files a/badger_os/examples/icon-image.jpg and /dev/null differ diff --git a/badger_os/examples/icon-image.png b/badger_os/examples/icon-image.png new file mode 100644 index 0000000..914cdb7 Binary files /dev/null and b/badger_os/examples/icon-image.png differ diff --git a/badger_os/examples/icon-info.jpg b/badger_os/examples/icon-info.jpg deleted file mode 100644 index 4a43961..0000000 Binary files a/badger_os/examples/icon-info.jpg and /dev/null differ diff --git a/badger_os/examples/icon-info.png b/badger_os/examples/icon-info.png new file mode 100644 index 0000000..3a52c20 Binary files /dev/null and b/badger_os/examples/icon-info.png differ diff --git a/badger_os/examples/icon-list.jpg b/badger_os/examples/icon-list.jpg deleted file mode 100644 index e9552dd..0000000 Binary files a/badger_os/examples/icon-list.jpg and /dev/null differ diff --git a/badger_os/examples/icon-list.png b/badger_os/examples/icon-list.png new file mode 100644 index 0000000..c31696b Binary files /dev/null and b/badger_os/examples/icon-list.png differ diff --git a/badger_os/examples/icon-net-info.jpg b/badger_os/examples/icon-net-info.jpg deleted file mode 100644 index f581777..0000000 Binary files a/badger_os/examples/icon-net-info.jpg and /dev/null differ diff --git a/badger_os/examples/icon-net-info.png b/badger_os/examples/icon-net-info.png new file mode 100644 index 0000000..fe1349f Binary files /dev/null and b/badger_os/examples/icon-net-info.png differ diff --git a/badger_os/examples/icon-news.jpg b/badger_os/examples/icon-news.jpg deleted file mode 100644 index 0c281d3..0000000 Binary files a/badger_os/examples/icon-news.jpg and /dev/null differ diff --git a/badger_os/examples/icon-news.png b/badger_os/examples/icon-news.png new file mode 100644 index 0000000..d2eb8ba Binary files /dev/null and b/badger_os/examples/icon-news.png differ diff --git a/badger_os/examples/icon-qrgen.jpg b/badger_os/examples/icon-qrgen.jpg deleted file mode 100644 index 1f31e66..0000000 Binary files a/badger_os/examples/icon-qrgen.jpg and /dev/null differ diff --git a/badger_os/examples/icon-qrgen.png b/badger_os/examples/icon-qrgen.png new file mode 100644 index 0000000..d67cbd6 Binary files /dev/null and b/badger_os/examples/icon-qrgen.png differ diff --git a/badger_os/examples/icon-weather.jpg b/badger_os/examples/icon-weather.jpg deleted file mode 100644 index 35d3bd0..0000000 Binary files a/badger_os/examples/icon-weather.jpg and /dev/null differ diff --git a/badger_os/examples/icon-weather.png b/badger_os/examples/icon-weather.png new file mode 100644 index 0000000..9658a3d Binary files /dev/null and b/badger_os/examples/icon-weather.png differ diff --git a/badger_os/examples/image.py b/badger_os/examples/image.py index ab72e91..6261fbd 100644 --- a/badger_os/examples/image.py +++ b/badger_os/examples/image.py @@ -3,6 +3,7 @@ from badger2040 import HEIGHT, WIDTH import badger_os import jpegdec +import pngdec TOTAL_IMAGES = 0 @@ -14,11 +15,12 @@ display.set_update_speed(badger2040.UPDATE_NORMAL) jpeg = jpegdec.JPEG(display.display) +png = pngdec.PNG(display.display) # Load images try: - IMAGES = [f for f in os.listdir("/images") if f.endswith(".jpg")] + IMAGES = [f for f in os.listdir("/images") if f.endswith(".jpg") or f.endswith(".png")] TOTAL_IMAGES = len(IMAGES) except OSError: pass @@ -32,18 +34,24 @@ def show_image(n): file = IMAGES[n] - name = file.split(".")[0] - jpeg.open_file("/images/{}".format(file)) - jpeg.decode() + name, ext = file.split(".") + + try: + png.open_file("/images/{}".format(file)) + png.decode() + except (OSError, RuntimeError): + jpeg.open_file("/images/{}".format(file)) + jpeg.decode() if state["show_info"]: - name_length = display.measure_text(name, 0.5) + label = f"{name} ({ext})" + name_length = display.measure_text(label, 0.5) display.set_pen(0) display.rectangle(0, HEIGHT - 21, name_length + 11, 21) display.set_pen(15) display.rectangle(0, HEIGHT - 20, name_length + 10, 20) display.set_pen(0) - display.text(name, 5, HEIGHT - 10, WIDTH, 0.5) + display.text(label, 5, HEIGHT - 10, WIDTH, 0.5) for i in range(TOTAL_IMAGES): x = 286 diff --git a/badger_os/examples/weather.py b/badger_os/examples/weather.py index c5692fa..f2f7e8d 100644 --- a/badger_os/examples/weather.py +++ b/badger_os/examples/weather.py @@ -4,7 +4,7 @@ import badger2040 from badger2040 import WIDTH import urequests -import jpegdec +import pngdec # Set your latitude/longitude here (find yours by right clicking in Google Maps!) LAT = 53.38609085276884 @@ -18,7 +18,7 @@ display.led(128) display.set_update_speed(2) -jpeg = jpegdec.JPEG(display.display) +png = pngdec.PNG(display.display) # Connects to the wireless network. Ensure you have entered your details in WIFI_CONFIG.py :). display.connect() @@ -72,16 +72,16 @@ def draw_page(): # Weather codes from https://open-meteo.com/en/docs # Weather icons from https://fontawesome.com/ if weathercode in [71, 73, 75, 77, 85, 86]: # codes for snow - jpeg.open_file("/icons/icon-snow.jpg") + png.open_file("/icons/icon-snow.png") elif weathercode in [51, 53, 55, 56, 57, 61, 63, 65, 66, 67, 80, 81, 82]: # codes for rain - jpeg.open_file("/icons/icon-rain.jpg") + png.open_file("/icons/icon-rain.png") elif weathercode in [1, 2, 3, 45, 48]: # codes for cloud - jpeg.open_file("/icons/icon-cloud.jpg") + png.open_file("/icons/icon-cloud.png") elif weathercode in [0]: # codes for sun - jpeg.open_file("/icons/icon-sun.jpg") + png.open_file("/icons/icon-sun.png") elif weathercode in [95, 96, 99]: # codes for storm - jpeg.open_file("/icons/icon-storm.jpg") - jpeg.decode(13, 40, jpegdec.JPEG_SCALE_FULL) + png.open_file("/icons/icon-storm.png") + png.decode(13, 40) display.set_pen(0) display.text(f"Temperature: {temperature}°C", int(WIDTH / 3), 28, WIDTH - 105, 2) display.text(f"Wind Speed: {windspeed}kmph", int(WIDTH / 3), 48, WIDTH - 105, 2) diff --git a/badger_os/icons/icon-cloud.jpg b/badger_os/icons/icon-cloud.jpg deleted file mode 100644 index b1b1e70..0000000 Binary files a/badger_os/icons/icon-cloud.jpg and /dev/null differ diff --git a/badger_os/icons/icon-cloud.png b/badger_os/icons/icon-cloud.png new file mode 100644 index 0000000..ee4126c Binary files /dev/null and b/badger_os/icons/icon-cloud.png differ diff --git a/badger_os/icons/icon-rain.jpg b/badger_os/icons/icon-rain.jpg deleted file mode 100644 index e0d536d..0000000 Binary files a/badger_os/icons/icon-rain.jpg and /dev/null differ diff --git a/badger_os/icons/icon-rain.png b/badger_os/icons/icon-rain.png new file mode 100644 index 0000000..6865329 Binary files /dev/null and b/badger_os/icons/icon-rain.png differ diff --git a/badger_os/icons/icon-snow.jpg b/badger_os/icons/icon-snow.jpg deleted file mode 100644 index db18190..0000000 Binary files a/badger_os/icons/icon-snow.jpg and /dev/null differ diff --git a/badger_os/icons/icon-snow.png b/badger_os/icons/icon-snow.png new file mode 100644 index 0000000..077c170 Binary files /dev/null and b/badger_os/icons/icon-snow.png differ diff --git a/badger_os/icons/icon-storm.jpg b/badger_os/icons/icon-storm.jpg deleted file mode 100644 index b01a937..0000000 Binary files a/badger_os/icons/icon-storm.jpg and /dev/null differ diff --git a/badger_os/icons/icon-storm.png b/badger_os/icons/icon-storm.png new file mode 100644 index 0000000..288a3fc Binary files /dev/null and b/badger_os/icons/icon-storm.png differ diff --git a/badger_os/icons/icon-sun.jpg b/badger_os/icons/icon-sun.jpg deleted file mode 100644 index 6c3703d..0000000 Binary files a/badger_os/icons/icon-sun.jpg and /dev/null differ diff --git a/badger_os/icons/icon-sun.png b/badger_os/icons/icon-sun.png new file mode 100644 index 0000000..709eecd Binary files /dev/null and b/badger_os/icons/icon-sun.png differ diff --git a/badger_os/launcher.py b/badger_os/launcher.py index 9a4c0ff..a860633 100644 --- a/badger_os/launcher.py +++ b/badger_os/launcher.py @@ -4,6 +4,7 @@ import math import badger2040 import badger_os +import pngdec import jpegdec APP_DIR = "/examples" @@ -26,6 +27,7 @@ display.set_font("bitmap8") display.led(128) +png = pngdec.PNG(display.display) jpeg = jpegdec.JPEG(display.display) state = { @@ -90,10 +92,15 @@ def render(): x = centers[i] label = examples[i + (state["page"] * 3)] icon_label = label.replace("_", "-") - icon = f"{APP_DIR}/icon-{icon_label}.jpg" + icon = f"{APP_DIR}/icon-{icon_label}" label = label.replace("_", " ") - jpeg.open_file(icon) - jpeg.decode(x - 26, 30) + for lib, ext in [(png, "png"), (jpeg, "jpg")]: + try: + lib.open_file(f"{icon}.{ext}") + lib.decode(x - 26, 30) + break + except (OSError, RuntimeError): + continue display.set_pen(0) w = display.measure_text(label, FONT_SIZE) display.text(label, int(x - (w / 2)), 16 + 80, WIDTH, FONT_SIZE) diff --git a/firmware/932f76c6ba64c5a3e68de3324556d9979f09303b.patch b/firmware/932f76c6ba64c5a3e68de3324556d9979f09303b.patch new file mode 100644 index 0000000..ef01ce8 --- /dev/null +++ b/firmware/932f76c6ba64c5a3e68de3324556d9979f09303b.patch @@ -0,0 +1,44 @@ +From 932f76c6ba64c5a3e68de3324556d9979f09303b Mon Sep 17 00:00:00 2001 +From: Phil Howard +Date: Tue, 27 Feb 2024 10:19:35 +0000 +Subject: [PATCH] rp2/CMakeLists: Use MICROPY_BOARD_DIR to find pins.csv. + +Assuming that ${MICROPY_PORT_DIR}/boards/${MICROPY_BOARD} is equal to +${MICROPY_BOARD_DIR} is not valid, because the latter could point to a path +outside the main MicroPython repository. + +Replace this path with the canonical ${MICROPY_BOARD_DIR} so that pins.csv +is correctly located when building against out-of-tree board definitions. + +Additionally remove MICROPY_BOARDS_DIR to discourage similar mistakes. + +Signed-off-by: Phil Howard +--- + ports/rp2/CMakeLists.txt | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +diff --git a/ports/rp2/CMakeLists.txt b/ports/rp2/CMakeLists.txt +index f86224a5c067..d3ecee586054 100644 +--- a/ports/rp2/CMakeLists.txt ++++ b/ports/rp2/CMakeLists.txt +@@ -530,15 +530,14 @@ endforeach() + # Include the main MicroPython cmake rules. + include(${MICROPY_DIR}/py/mkrules.cmake) + +-set(MICROPY_BOARDS_DIR "${MICROPY_PORT_DIR}/boards") +-set(GEN_PINS_AF_CSV "${MICROPY_BOARDS_DIR}/rp2_af.csv") +-set(GEN_PINS_PREFIX "${MICROPY_BOARDS_DIR}/rp2_prefix.c") +-set(GEN_PINS_MKPINS "${MICROPY_BOARDS_DIR}/make-pins.py") ++set(GEN_PINS_AF_CSV "${MICROPY_PORT_DIR}/boards/rp2_af.csv") ++set(GEN_PINS_PREFIX "${MICROPY_PORT_DIR}/boards/rp2_prefix.c") ++set(GEN_PINS_MKPINS "${MICROPY_PORT_DIR}/boards/make-pins.py") + set(GEN_PINS_SRC "${CMAKE_BINARY_DIR}/pins_${MICROPY_BOARD}.c") + set(GEN_PINS_HDR "${MICROPY_GENHDR_DIR}/pins.h") + +-if(EXISTS "${MICROPY_BOARDS_DIR}/${MICROPY_BOARD}/pins.csv") +- set(GEN_PINS_BOARD_CSV "${MICROPY_BOARDS_DIR}/${MICROPY_BOARD}/pins.csv") ++if(EXISTS "${MICROPY_BOARD_DIR}/pins.csv") ++ set(GEN_PINS_BOARD_CSV "${MICROPY_BOARD_DIR}/pins.csv") + set(GEN_PINS_CSV_ARG --board-csv "${GEN_PINS_BOARD_CSV}") + endif() + diff --git a/firmware/PIMORONI_BADGER2040/micropython.cmake b/firmware/PIMORONI_BADGER2040/micropython.cmake index b1207d4..10c87da 100644 --- a/firmware/PIMORONI_BADGER2040/micropython.cmake +++ b/firmware/PIMORONI_BADGER2040/micropython.cmake @@ -22,6 +22,7 @@ include(picographics/micropython) # Pico Graphics Extra include(jpegdec/micropython) +include(pngdec/micropython) include(qrcode/micropython/micropython) # Sensors & Breakouts diff --git a/firmware/PIMORONI_BADGER2040/pins.csv b/firmware/PIMORONI_BADGER2040/pins.csv new file mode 100644 index 0000000..75f0d4f --- /dev/null +++ b/firmware/PIMORONI_BADGER2040/pins.csv @@ -0,0 +1,35 @@ +GP0,GPIO0 +GP1,GPIO1 +GP2,GPIO2 +GP3,GPIO3 +GP4,GPIO4 +GP5,GPIO5 +GP6,GPIO6 +GP7,GPIO7 +GP8,GPIO8 +GP9,GPIO9 +GP10,GPIO10 +GP11,GPIO11 +GP12,GPIO12 +GP13,GPIO13 +GP14,GPIO14 +GP15,GPIO15 +GP16,GPIO16 +GP17,GPIO17 +GP18,GPIO18 +GP19,GPIO19 +GP20,GPIO20 +GP21,GPIO21 +GP22,GPIO22 +GP25,GPIO25 +GP26,GPIO26 +GP27,GPIO27 +GP28,GPIO28 +DOWN,GPIO11 +A,GPIO12 +B,GPIO13 +C,GPIO14 +UP,GPIO15 +EN_3V3,GPIO10 +LED,GPIO25 +BUSY,GPIO26 \ No newline at end of file diff --git a/firmware/PIMORONI_BADGER2040/uf2-manifest.txt b/firmware/PIMORONI_BADGER2040/uf2-manifest.txt index 18ef4e1..74e9cb9 100644 --- a/firmware/PIMORONI_BADGER2040/uf2-manifest.txt +++ b/firmware/PIMORONI_BADGER2040/uf2-manifest.txt @@ -1,6 +1,6 @@ launcher.py main.py -examples/*.jpg +examples/*.png examples/badge.py examples/clock.py examples/ebook.py @@ -15,4 +15,4 @@ images/*.txt badges/*.txt badges/*.jpg books/*.txt -icons/*.jpg \ No newline at end of file +icons/*.png \ No newline at end of file diff --git a/firmware/PIMORONI_BADGER2040W/lib/badger2040.py b/firmware/PIMORONI_BADGER2040W/lib/badger2040.py index 60cbc56..b37db40 100644 --- a/firmware/PIMORONI_BADGER2040W/lib/badger2040.py +++ b/firmware/PIMORONI_BADGER2040W/lib/badger2040.py @@ -241,8 +241,10 @@ def status_handler(self, mode, status, ip): if status: self.display.text("Connected!", 10, 10, 300, 0.5) self.display.text(ip, 10, 30, 300, 0.5) - else: + elif status is None: self.display.text("Connecting...", 10, 10, 300, 0.5) + else: + self.display.text("Connection failed!", 10, 10, 300, 0.5) self.update() def isconnected(self): @@ -260,10 +262,13 @@ def connect(self, **args): import gc status_handler = args.get("status_handler", self.status_handler) + error_handler = args.get("error_handler", None) + client_timeout = args.get("timeout", 60) + retries = args.get("retries", 2) if WIFI_CONFIG.COUNTRY == "": raise RuntimeError("You must populate WIFI_CONFIG.py for networking.") - network_manager = NetworkManager(WIFI_CONFIG.COUNTRY, status_handler=status_handler) + network_manager = NetworkManager(WIFI_CONFIG.COUNTRY, client_timeout=client_timeout, status_handler=status_handler, error_handler=error_handler, retries=retries) uasyncio.get_event_loop().run_until_complete(network_manager.client(WIFI_CONFIG.SSID, WIFI_CONFIG.PSK)) gc.collect() diff --git a/firmware/PIMORONI_BADGER2040W/lib/network_manager.py b/firmware/PIMORONI_BADGER2040W/lib/network_manager.py index fb21c2c..5211aa3 100644 --- a/firmware/PIMORONI_BADGER2040W/lib/network_manager.py +++ b/firmware/PIMORONI_BADGER2040W/lib/network_manager.py @@ -7,11 +7,12 @@ class NetworkManager: _ifname = ("Client", "Access Point") - def __init__(self, country="GB", client_timeout=60, access_point_timeout=5, status_handler=None, error_handler=None): + def __init__(self, country="GB", client_timeout=60, access_point_timeout=5, status_handler=None, error_handler=None, retries=2): rp2.country(country) self._ap_if = network.WLAN(network.AP_IF) self._sta_if = network.WLAN(network.STA_IF) + self._retries = retries self._mode = network.STA_IF self._client_timeout = client_timeout self._access_point_timeout = access_point_timeout @@ -53,7 +54,19 @@ def disconnect(self): async def wait(self, mode): while not self.isconnected(): self._handle_status(mode, None) + if mode == network.STA_IF: + if self._sta_if.status() == network.STAT_CONNECT_FAIL: + self._handle_status(mode, False) + return False + if self._sta_if.status() == network.STAT_NO_AP_FOUND: + self._handle_error(mode, "AP not found!") + return False + if self._sta_if.status() == network.STAT_WRONG_PASSWORD: + self._handle_error(mode, "Wrong password!") + return False await uasyncio.sleep_ms(1000) + self._handle_status(mode, True) + return True def _handle_status(self, mode, status): if callable(self._status_handler): @@ -75,16 +88,20 @@ async def client(self, ssid, psk): self._sta_if.active(True) self._sta_if.config(pm=0xa11140) - self._sta_if.connect(ssid, psk) - try: - await uasyncio.wait_for(self.wait(network.STA_IF), self._client_timeout) - self._handle_status(network.STA_IF, True) + for _ in range(self._retries): + try: + self._sta_if.connect(ssid, psk) + result = await uasyncio.wait_for(self.wait(network.STA_IF), self._client_timeout) + if result: + return - except uasyncio.TimeoutError: - self._sta_if.active(False) - self._handle_status(network.STA_IF, False) - self._handle_error(network.STA_IF, "WIFI Client Failed") + except uasyncio.TimeoutError: + pass + + self._sta_if.active(False) + self._handle_status(network.STA_IF, False) + self._handle_error(network.STA_IF, "WIFI Client Failed") async def access_point(self): if self._ap_if.isconnected(): @@ -99,8 +116,7 @@ async def access_point(self): self._ap_if.active(True) try: - await uasyncio.wait_for(self.wait(network.AP_IF), self._access_point_timeout) - self._handle_status(network.AP_IF, True) + _ = await uasyncio.wait_for(self.wait(network.AP_IF), self._access_point_timeout) except uasyncio.TimeoutError: self._sta_if.active(False) diff --git a/firmware/PIMORONI_BADGER2040W/micropython.cmake b/firmware/PIMORONI_BADGER2040W/micropython.cmake index 2901f6c..54dc032 100644 --- a/firmware/PIMORONI_BADGER2040W/micropython.cmake +++ b/firmware/PIMORONI_BADGER2040W/micropython.cmake @@ -22,6 +22,7 @@ include(picographics/micropython) # Pico Graphics Extra include(jpegdec/micropython) +include(pngdec/micropython) include(qrcode/micropython/micropython) # Sensors & Breakouts diff --git a/firmware/PIMORONI_BADGER2040W/pins.csv b/firmware/PIMORONI_BADGER2040W/pins.csv index 012bc7c..9d564be 100644 --- a/firmware/PIMORONI_BADGER2040W/pins.csv +++ b/firmware/PIMORONI_BADGER2040W/pins.csv @@ -24,7 +24,16 @@ GP22,GPIO22 GP26,GPIO26 GP27,GPIO27 GP28,GPIO28 +DOWN,GPIO11 +ALARM,GPIO8 +EN_3V3,GPIO10 +A,GPIO12 +B,GPIO13 +C,GPIO14 +UP,GPIO15 +LED,GPIO22 +BUSY,GPIO26 WL_GPIO0,EXT_GPIO0 WL_GPIO1,EXT_GPIO1 WL_GPIO2,EXT_GPIO2 -LED,EXT_GPIO0 \ No newline at end of file +WL_LED,EXT_GPIO0 \ No newline at end of file diff --git a/firmware/PIMORONI_BADGER2040W/uf2-manifest.txt b/firmware/PIMORONI_BADGER2040W/uf2-manifest.txt index a3f2f44..64f93f6 100644 --- a/firmware/PIMORONI_BADGER2040W/uf2-manifest.txt +++ b/firmware/PIMORONI_BADGER2040W/uf2-manifest.txt @@ -1,9 +1,9 @@ *.py -examples/*.jpg +examples/*.png examples/*.py images/*.jpg images/*.txt badges/*.txt badges/*.jpg books/*.txt -icons/*.jpg \ No newline at end of file +icons/*.png \ No newline at end of file diff --git a/firmware/micropython_nano_specs.patch b/firmware/micropython_nano_specs.patch index 098c0bf..fbfb947 100644 --- a/firmware/micropython_nano_specs.patch +++ b/firmware/micropython_nano_specs.patch @@ -1,11 +1,11 @@ diff --git a/ports/rp2/CMakeLists.txt b/ports/rp2/CMakeLists.txt -index 094031c6852a..5f268414c08f 100644 +index e058c0a..fd97871 100644 --- a/ports/rp2/CMakeLists.txt +++ b/ports/rp2/CMakeLists.txt -@@ -374,6 +374,15 @@ target_compile_options(${MICROPY_TARGET} PRIVATE - target_link_options(${MICROPY_TARGET} PRIVATE - -Wl,--defsym=__micropy_c_heap_size__=${MICROPY_C_HEAP_SIZE} +@@ -455,6 +455,16 @@ target_link_options(${MICROPY_TARGET} PRIVATE + -Wl,--wrap=dcd_event_handler ) + +# Do not include stack unwinding & exception handling for C++ user modules +target_compile_definitions(usermod INTERFACE PICO_CXX_ENABLE_EXCEPTIONS=0) +target_compile_options(usermod INTERFACE $<$: @@ -15,6 +15,7 @@ index 094031c6852a..5f268414c08f 100644 + -fno-use-cxa-atexit +>) +target_link_options(usermod INTERFACE -specs=nano.specs) - ++ + # Apply optimisations to performance-critical source code. set_source_files_properties( - ${PICO_SDK_PATH}/src/rp2_common/pico_double/double_math.c + ${MICROPY_PY_DIR}/map.c diff --git a/firmware/modules/wakeup/wakeup.c b/firmware/modules/wakeup/wakeup.c index f570f64..22b96fd 100644 --- a/firmware/modules/wakeup/wakeup.c +++ b/firmware/modules/wakeup/wakeup.c @@ -1,14 +1,14 @@ #include "wakeup.h" -STATIC MP_DEFINE_CONST_FUN_OBJ_0(Wakeup_get_gpio_state_obj, Wakeup_get_gpio_state); -STATIC MP_DEFINE_CONST_FUN_OBJ_0(Wakeup_reset_gpio_state_obj, Wakeup_reset_gpio_state); +static MP_DEFINE_CONST_FUN_OBJ_0(Wakeup_get_gpio_state_obj, Wakeup_get_gpio_state); +static MP_DEFINE_CONST_FUN_OBJ_0(Wakeup_reset_gpio_state_obj, Wakeup_reset_gpio_state); -STATIC const mp_map_elem_t wakeup_globals_table[] = { +static const mp_map_elem_t wakeup_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_wakeup) }, { MP_ROM_QSTR(MP_QSTR_get_gpio_state), MP_ROM_PTR(&Wakeup_get_gpio_state_obj) }, { MP_ROM_QSTR(MP_QSTR_reset_gpio_state), MP_ROM_PTR(&Wakeup_reset_gpio_state_obj) } }; -STATIC MP_DEFINE_CONST_DICT(mp_module_wakeup_globals, wakeup_globals_table); +static MP_DEFINE_CONST_DICT(mp_module_wakeup_globals, wakeup_globals_table); const mp_obj_module_t wakeup_user_cmodule = { .base = { &mp_type_module },